<?php

!defined('IN_VIFRAME') && die('Access Denied.');

class Factory extends TLib {

	protected static
		$_Instances  = array(),
		$_Inited     = array(),
		$_ClassNames = array();

	public static function getInstance($key, $init = false, $param = array()) {
		if (isset(self::$_Instances[$key])) {
			return self::$_Instances[$key];
		} else {
			if (isset(self::$_ClassNames[$key])) {
				$className = self::$_ClassNames[$key];
			} else {
				$className = "C$key";
			}
			if (class_exists($className)){
				$instance  = new $className();
			} else {
				return false;
			}
			self::$_Instances[$key] = & $instance;
		}
		
		if ($init) {
			self::initInstance($key, $params);
		}
		
		return $instance;
	}

	public static function setInstance($key,$instance) {
		self::$_Instances[$key] = $instance;
		
		return true;
	}

	public static function removeInstance($key) {
		unset(self::$_Instances[$key]);
		unset(self::$_Inited[$key]);
		
		return true;
	}

	public static function removeAllInstances() {
		self::$_Instances = array();
		self::$_Inited    = array();
		
		return true;
	}

	public static function initInstance($key, $params) {
		if (!isset(self::$_Instances[$key])) {
			$instance = self::getInstance($key, false);
		} else {
			$instance = self::$_Instances[$key];
		}
		
		if (!$instance instanceof TClass) {
			return false;
		}
		
		if (self::isInited($key)) {
			self::$_Inited[$key] = true;
			
			return call_user_func_array(array($instance, 'init'), $param);
		} else {
			return false;
		}
	}
	
	public static function reinitInstance($key, $params) {
		if (!isset(self::$_Instances[$key])) {
			$instance = self::getInstance($key);
		} else {
			$instance = self::$_Instances[$key];
		}
		
		if (!$instance instanceof TClass) {
			return false;
		}
		
		self::$_Inited[$key] = true;
		
		return call_user_func_array(array($instance, 'init'), $param);
	}
	
	public static function isInited($key) {
		return isset(self::$_Inited[$key]) ? self::$_Inited[$key]
				: false;
	}
	
	public static function getClassName($key) {
		return isset(self::$_ClassNames[$key]) ? self::$_ClassNames[$key]
				: false;
	}
	
	public static function getAllClassNames() {
		return self::$_ClassNames;
	}

	public static function removeClassName($key) {
		unset(self::$_ClassNames[$key]);
		
		return true;
	}

	public static function removeAllClassNames() {
		self::$_ClassNames = array();
		
		return true;
	}

	public static function setClassName($key,$value = null) {
		if (is_array($key)) {
			self::$_ClassNames = $key + self::$_ClassNames;
		} else {
			self::$_ClassNames[$key] = $value;
		}
		
		return true;
	}
}